/**
 * Created by 1257D on 2016-03-23.
 */
define(
    ["app/core/base",
        "app/core/util",
        "../echartsMeta",
        "jquery",
        "underscore",
        'JSONParse',
        'loglevel',
        "echarts"
    ],
    function (Chart, Util, Meta, $, _, JSON, log, ec) {

        var property = {
            name: '通用属性',
            config: "property",
            option: []
                .concat($.extend(true, [], Meta.titleProperties))
                .concat($.extend(true, [], Meta.legendProperties))
                .concat($.extend(true, [], Meta.tooltipProperties))
                .concat($.extend(true, [], Meta.toolboxProperties))
                .concat($.extend(true, [], Meta.visualMapProperties))
                .concat([
                    {
                        group: '序列',
                        id: 'f53a0a43-6d1b-43e0-b514-122a8b155ece',
                        name: '序列',
                        type: 'group',
                        items: [],
                        option: [
                            {
                                id: '8d613598-8e08-49ce-908e-7524c305910f',
                                name: '序列名称',
                                enable: true,
                                type: 'text',
                                value: '',
                                link: 'name',
                                tooltip: '序列名称，用于legend'
                            },
                            {
                                id: '17994381-e1fe-4551-a852-a5a0571ed899',
                                name: '序列绑定',
                                enable: true,
                                type: 'seriesBinding',
                                dataset: '',
                                dimension: '',
                                measure: '',
                                tooltip: '序列绑定设置，与数据集关系'
                            },
                            {
                                id: 'a320684c-8ca5-49f0-aab7-853e0fde9e5c',
                                name: '过滤列名称',
                                enable: false,
                                type: 'text',
                                value: '',
                                default: '',
                                tooltip: '绑定数据集，客户端过滤字段列名称'
                            },
                            {
                                id: '96f30ae6-6fe0-4faa-8b7f-a302a49a0434',
                                name: '过滤列默认值',
                                enable: false,
                                type: 'text',
                                value: '',
                                default: '',
                                tooltip: '绑定数据集，客户端过滤字段默认值'
                            }
                        ],
                        link: 'series',
                        tooltip: '字段说明:<br/>分组控件，支持动态扩展，内部可增加支持的类型属性'
                    }
                ]).concat($.extend(true, [], Meta.otherProperties)),
            //需要针对组件映射属性至组件Options
            MapOption: function (option) {
                Util.linkOption(this.option, option);
            }
        };

        var heatmap = Chart.extend({
            constructor: function (layout) {
                this._layout = layout;
                this._lastdata = null;
                this._container = null;
                this._chart = null;

                var hours = ['12a', '1a', '2a', '3a', '4a', '5a', '6a', '7a', '8a', '9a', '10a', '11a', '12p', '1p', '2p', '3p', '4p', '5p', '6p', '7p', '8p', '9p', '10p', '11p'];
                var days = ['Saturday', 'Friday', 'Thursday', 'Wednesday', 'Tuesday', 'Monday', 'Sunday'];

                var data = [[0, 0, 5], [0, 1, 1], [0, 2, 0], [0, 3, 0], [0, 4, 0], [0, 5, 0], [0, 6, 0], [0, 7, 0], [0, 8, 0], [0, 9, 0], [0, 10, 0], [0, 11, 2], [0, 12, 4], [0, 13, 1], [0, 14, 1], [0, 15, 3], [0, 16, 4], [0, 17, 6], [0, 18, 4], [0, 19, 4], [0, 20, 3], [0, 21, 3], [0, 22, 2], [0, 23, 5], [1, 0, 7], [1, 1, 0], [1, 2, 0], [1, 3, 0], [1, 4, 0], [1, 5, 0], [1, 6, 0], [1, 7, 0], [1, 8, 0], [1, 9, 0], [1, 10, 5], [1, 11, 2], [1, 12, 2], [1, 13, 6], [1, 14, 9], [1, 15, 11], [1, 16, 6], [1, 17, 7], [1, 18, 8], [1, 19, 12], [1, 20, 5], [1, 21, 5], [1, 22, 7], [1, 23, 2], [2, 0, 1], [2, 1, 1], [2, 2, 0], [2, 3, 0], [2, 4, 0], [2, 5, 0], [2, 6, 0], [2, 7, 0], [2, 8, 0], [2, 9, 0], [2, 10, 3], [2, 11, 2], [2, 12, 1], [2, 13, 9], [2, 14, 8], [2, 15, 10], [2, 16, 6], [2, 17, 5], [2, 18, 5], [2, 19, 5], [2, 20, 7], [2, 21, 4], [2, 22, 2], [2, 23, 4], [3, 0, 7], [3, 1, 3], [3, 2, 0], [3, 3, 0], [3, 4, 0], [3, 5, 0], [3, 6, 0], [3, 7, 0], [3, 8, 1], [3, 9, 0], [3, 10, 5], [3, 11, 4], [3, 12, 7], [3, 13, 14], [3, 14, 13], [3, 15, 12], [3, 16, 9], [3, 17, 5], [3, 18, 5], [3, 19, 10], [3, 20, 6], [3, 21, 4], [3, 22, 4], [3, 23, 1], [4, 0, 1], [4, 1, 3], [4, 2, 0], [4, 3, 0], [4, 4, 0], [4, 5, 1], [4, 6, 0], [4, 7, 0], [4, 8, 0], [4, 9, 2], [4, 10, 4], [4, 11, 4], [4, 12, 2], [4, 13, 4], [4, 14, 4], [4, 15, 14], [4, 16, 12], [4, 17, 1], [4, 18, 8], [4, 19, 5], [4, 20, 3], [4, 21, 7], [4, 22, 3], [4, 23, 0], [5, 0, 2], [5, 1, 1], [5, 2, 0], [5, 3, 3], [5, 4, 0], [5, 5, 0], [5, 6, 0], [5, 7, 0], [5, 8, 2], [5, 9, 0], [5, 10, 4], [5, 11, 1], [5, 12, 5], [5, 13, 10], [5, 14, 5], [5, 15, 7], [5, 16, 11], [5, 17, 6], [5, 18, 0], [5, 19, 5], [5, 20, 3], [5, 21, 4], [5, 22, 2], [5, 23, 0], [6, 0, 1], [6, 1, 0], [6, 2, 0], [6, 3, 0], [6, 4, 0], [6, 5, 0], [6, 6, 0], [6, 7, 0], [6, 8, 0], [6, 9, 0], [6, 10, 1], [6, 11, 0], [6, 12, 2], [6, 13, 1], [6, 14, 3], [6, 15, 4], [6, 16, 0], [6, 17, 0], [6, 18, 0], [6, 19, 0], [6, 20, 1], [6, 21, 2], [6, 22, 2], [6, 23, 6]
                ];

                data = data.map(function (item) {
                    return [item[1], item[0], item[2] || '-'];
                });

                this._option = {
                    Binding: [],
                    Events: [],
                    Extend: $.extend(true, {}, property),
                    Option: {
                        tooltip: {
                            position: 'top'
                        },
                        animation: true,
                        grid: {
                            height: '65%',
                            y: '10%'
                        },
                        xAxis: {
                            type: 'category',
                            data: hours
                        },
                        yAxis: {
                            type: 'category',
                            data: days
                        },
                        visualMap: {
                            min: 1,
                            max: 10,
                            color: ['#be454f', '#f6efaa'],
                            calculable: true,
                            orient: 'horizontal',
                            left: 'center',
                            bottom: '0%',
                        },
                        series: [{
                            name: 'Punch Card',
                            type: 'heatmap',
                            data: data,
                            label: {
                                normal: {
                                    show: true
                                }
                            },
                            itemStyle: {
                                emphasis: {
                                    shadowBlur: 10,
                                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                                }
                            }
                        }]
                    }
                };
            },
            init: function (element) {
                try {
                    this._container = element;
                    this._chart = ec.init(element, null, {
                        renderer: 'canvas'
                    });
                    this._bindEvent();
                } catch (e) {
                    log.error(e);
                }
            },
            //TODO:需要重写的部分
            _bindEvent: function () {
                var _this = this;
                this._chart.on("click", function (param) {
                    if (_this._layout
                        && _this._layout.navigate
                        && _this._option.Events
                        && _this._option.Events.length > 0) {

                        var registerEvent = _.findWhere(_this._option.Events, {Event: "SeriesClick"});
                        if (registerEvent) {
                            var pageId = registerEvent.PageId;
                            var params = registerEvent.Params;
                            var args = [];
                            var dParam = _.findWhere(params, {Value: "Dimension"});
                            if (dParam && dParam.ParamName) {
                                args.push({
                                    ParamName: dParam.ParamName,
                                    ParamValue: param.name
                                });
                            }
                            var mParam = _.findWhere(params, {Value: "Measure"});
                            if (mParam && mParam.ParamName) {
                                args.push({
                                    ParamName: mParam.ParamName,
                                    ParamValue: param.value
                                });
                            }
                            var sParam = _.findWhere(params, {Value: "SeriesName"});
                            if (sParam && sParam.ParamName) {
                                args.push({
                                    ParamName: sParam.ParamName,
                                    ParamValue: param.seriesName
                                });
                            }
                            _this._layout.navigate(pageId, args);

                        }
                        param.event.event.preventDefault();
                    }
                });
                if (!this._filterDataHandle) {
                    this._filterDataHandle = function (params) {
                        _this.filterDataHandle.call(_this, params);
                    };
                }
                this._layout.removeListener("filterData", this._filterDataHandle);
                this._layout.addListener("filterData", this._filterDataHandle);
            },
            filterDataHandle: function (params) {
                var _this = this;
                var flag = false;
                var seriesItems = _.findWhere(_this._option.Extend.option, {type: 'group'});
                $.each(seriesItems.items, function (i, item) {
                    var filterColumn = _.findWhere(item.option, {name: '过滤列名称'});
                    var filterValue = _.findWhere(item.option, {name: '过滤列默认值'});

                    if (filterColumn && filterValue
                        && filterColumn.enable && filterValue.enable
                        && filterColumn.value !== "" && filterValue.value !== ""
                    ) {
                        for (var prop in params) {
                            if (!params.hasOwnProperty(prop)) continue;
                            if (filterColumn.value === prop) {
                                filterValue.value = params[prop];
                                flag = true;
                            }
                        }
                    }
                });
                if (flag && _this._lastdata) {
                    _this.setData(_this._lastdata);
                }
            },
            example: function () {
                try {
                    this._chart.setOption(this._option.Option, true);
                } catch (e) {
                    log.error(e);
                }
            },
            _readProperty: function () {
                try {
                    if (!this._option.Extend) return;
                    Util.deepMapOption(property, this._option.Extend, this._option.Option);
                } catch (e) {
                    log.error(e);
                }
            },
            //TODO:需要重写的部分
            _bindData: function (data) {
                var tables = data;
                var _this = this;


                //根据每个option自行查找，可通过id或name，这里因为只有一个group,因此通过type查找
                var seriesItems = _.findWhere(this._option.Extend.option, {type: 'group'});

                //清除工作
                if (seriesItems.items.length > 0) {
                    this._option.Option.legend.data = [];
                    $.each(this._option.Option.xAxis, function (i, xAxis) {
                        if (xAxis.type === "category") {
                            xAxis.data = [];
                        } else {
                            delete xAxis.data;
                        }
                    });
                    $.each(this._option.Option.yAxis, function (i, yAxis) {
                        if (yAxis.type === "category") {
                            yAxis.data = [];
                        } else {
                            delete yAxis.data;
                        }
                    });
                    var categoryAxis = this._option.Option.xAxis[0].type === "category" ? this._option.Option.xAxis[0] : this._option.Option.yAxis[0];
                }

                //绑定数据
                $.each(seriesItems.items, function (i, item) {
                    var bindProperty = _.findWhere(item.option, {type: 'seriesBinding'});
                    if (!bindProperty) return;

                    var dataSetCode = bindProperty.dataset;
                    var dimensionCode = bindProperty.dimension.ColumnCode;
                    var measureCode = bindProperty.measure.ColumnCode;

                    var nameProperty = _.findWhere(item.option, {name: '序列名称'});
                    if (nameProperty) {
                        _this._option.Option.legend.data.push(nameProperty.value);
                    }

                    if (dataSetCode && dimensionCode && measureCode) {
                        var table = tables[dataSetCode];

                        var binding = _.findWhere(_this._option.Binding, {DataSetCode: dataSetCode});
                        var dimension = _.findWhere(binding.Dimensions, {Code: dimensionCode}).Column;
                        var measure = _.findWhere(binding.Measures, {Code: measureCode}).Column;
                        var data = [];

                        table = _this._filterTable(item.option, table);
                        $.each(table, function (j, row) {
                            if (categoryAxis.data.indexOf(row[dimension]) === -1) {
                                categoryAxis.data.push(row[dimension]);
                            }
                            data.push(row[measure]);
                        });
                        if (_this._option.Option.series.length >= i + 1) {
                            _this._option.Option.series[i].data = data;
                        }
                    }
                });
            },
            _filterTable: function (option, table) {
                var filterColumn = _.findWhere(option, {name: '过滤列名称'});
                var filterValue = _.findWhere(option, {name: '过滤列默认值'});

                if (filterColumn && filterValue
                    && filterColumn.enable && filterValue.enable
                    && filterColumn.value !== "" && filterValue.value !== ""
                ) {
                    var tableCopy = _.map(table, _.clone);
                    return _.filter(tableCopy, function (row) {
                        return row[filterColumn.value] === filterValue.value;
                    });
                }
                return table;
            },
            setData: function (data) {
                try {
                    this._lastdata = data;

                    this._readProperty();

                    if (data
                        && this._option.Binding
                        && this._option.Binding.length > 0
                        && this._option.Extend) {

                        this._bindData(data);

                        this._readProperty();
                    }
                    this._chart.setOption(this._option.Option, true);

                    //Util.setEChartsMeta(this, this._container, this._option.Extend.option);
                } catch (e) {
                    log.error(e);
                }
            },
            setOption: function (option) {
                try {
                    return this._option = $.extend(true, {}, option);
                } catch (e) {
                    log.error(e);
                }
            },
            getOption: function () {
                try {
                    this._readProperty();
                } catch (e) {
                    log.error(e);
                }
                return this._option;
            },
            setTheme: function (theme) {
                try {
                    this._chart.setTheme(theme);
                } catch (e) {
                    log.error(e);
                }
            },
            resize: function () {
                try {
                    this._chart.resize();
                } catch (e) {
                    log.error(e);
                }
            },
            showLoading: function () {
                try {
                    if (this._layout && this._layout.showLoading) {
                        this._layout.showLoading(this);
                    }
                } catch (e) {
                    log.error(e);
                }
            },
            hideLoading: function () {
                try {
                    if (this._layout && this._layout.hideLoading) {
                        this._layout.hideLoading(this);
                    }
                } catch (e) {
                    log.error(e);
                }
            },
            dispose: function () {
                try {
                    this._chart.dispose();
                    this._layout.removeListener("filterData", this._filterDataHandle);
                } catch (e) {
                    log.error(e);
                }
            },
            getElement: function () {
                return this._container;
            },
            getChart: function () {
                return this._chart;
            }
        });

        return {
            Chart: heatmap,
            Property: property
        };
    });
